package cn.net.pap.pinyincut.core.algorithm.core;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 中文拼音切分
 */
public class PinyinSplitter {

//    public static void main(String[] args) {
//        System.out.println("woszgr" + " -> " + split("woszgr"));
//        System.out.println("wszhonggren" + " -> " + split("wszhonggren"));
//        System.out.println("qianb" + " -> " + split("qianb"));
//        System.out.println("qbi" + " -> " + split("qbi"));
//    }

    //此类用于缓存数据和方法返回数据
    private static class Wrapper {
        int cursor;
        Matcher shengMu;
        Matcher yunMu;
        Matcher stand;
    }

    // 韵母
    private static Pattern stand = Pattern.compile(
            "([ae](?:ng|i|n)|er|ao|ou|a|e)");
    //多拼音节韵母 ia iao ian iang iong ua uo uai uan uang üan
    //单拼音节
    private static Pattern yunmu = Pattern.compile(
            "(i(?:ong|ang|an|ao|a)|u(?:ang|an|ai|a|o)|[vu]an|[aeio]ng)|[aeu]i|[oi]u|[ivu]e|[aeiu]n|ao|er|a|o|e|i|u|v");
    private static Pattern shengmu = Pattern.compile(
            "(b|p|m|f|d|t|n|l|g|k|h|j|q|x|y|w|r|(?:z|c|s)h)|z|c|s");

    public static List<String> split(String unSplit) {
        if (!unSplit.matches("\\w+")) {
            //必须全部为字母
            return null;
        }
        Wrapper wrapper = new Wrapper();
        wrapper.shengMu = shengmu.matcher(unSplit);
        wrapper.yunMu = yunmu.matcher(unSplit);
        wrapper.stand = stand.matcher(unSplit);
        List<StringBuilder> ls = new LinkedList<StringBuilder>();
        while (wrapper.cursor < unSplit.length()) {
            String tmp = requestShengMu(wrapper);
            //判断是否有声母
            if (tmp == null) {
                tmp = requestStand(wrapper);
                assert tmp != null;
				/*
					如果开头有声母字母则无法到达此处
					如果开头为韵母则所有韵母均可由
						a、o、e、i、u、v
					单独组成，故tmp一定不为null
				*/
                ls.add(new StringBuilder(tmp));
                continue;
            }
            StringBuilder sb = new StringBuilder(tmp);
            tmp = requestYunMu(wrapper);
            if (tmp == null) {
                //只有声母没有韵母，不符合拼音规则
                ls.add(sb);
            } else {
                sb.append(tmp);
                ls.add(sb);
            }
        }
        //将拼音拼接后返回
        List<String> returnSplitList = new ArrayList<>();
        for (StringBuilder s : ls) {
            returnSplitList.add(s.toString());
        }
        return returnSplitList;
    }

    private static String requestYunMu(Wrapper wrapper) {
        if (wrapper.yunMu.find(wrapper.cursor)) {
            if (wrapper.cursor == wrapper.yunMu.start()) {
                wrapper.cursor = wrapper.yunMu.end();
                return wrapper.yunMu.group();
            }
        }
        return null;
    }

    private static String requestShengMu(Wrapper wrapper) {
        if (wrapper.shengMu.find(wrapper.cursor)) {
            if (wrapper.cursor == wrapper.shengMu.start()) {
                wrapper.cursor = wrapper.shengMu.end();
                return wrapper.shengMu.group();
            }
        }
        return null;
    }

    private static String requestStand(Wrapper wrapper) {
        if (wrapper.stand.find(wrapper.cursor)) {
            if (wrapper.cursor == wrapper.stand.start()) {
                wrapper.cursor = wrapper.stand.end();
                return wrapper.stand.group();
            }
        }
        return null;
    }
}
